﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.ComponentModel;
using System.Web.UI;
using System.IO;
using System.Net;
using PagamentoDigital.Properties;

namespace PagamentoDigital {
    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    [DefaultEvent("VendaEfetuada")]
    [DefaultProperty("Token")]
    [Description("Processa o retorno automático de uma venda através do Pagamento Digital")]
    [Designer(typeof(Design.RetornoPagamentoDigitalDesigner))]
    public class RetornoPagamentoDigital : Control {

        public delegate void VendaEfetuadaEventHandler(RetornoVenda retornoVenda);
        public event VendaEfetuadaEventHandler VendaEfetuada;

        public event EventHandler<VendaAutenticadaEventArgs> RetornoVerificado;
        public event EventHandler<VendaNaoAutenticadaEventArgs> VendaNaoAutenticada;
        public event EventHandler<FalhaProcessarRetornoEventArgs> FalhaProcessarRetorno;

        private string _url;
        private string _token;

        /// <summary>
        /// Token de Segurança
        /// </summary>
        public string Token {
            get {
                return _token;
            }
            set {
                _token = value;
            }
        }

        /// <summary>
        /// URL do Serviço de Retorno Automático
        /// </summary>
        public string Url {
            get {
                return _url;
            }
            set {
                _url = value;
            }
        }

        public RetornoPagamentoDigital() {
            this._url = Resources.PagamentoDigital_Verify;
        }

        public RetornoPagamentoDigital(string token)
            : this() {
            this._token = token;
        }

        protected override void OnLoad(EventArgs e) {
            if (this.Page != null) {
                this.ProcessarRetorno(this.Page.Request);
            }
        }

        public void ProcessarRetorno() {
            this.ProcessarRetorno(null);
        }

        public void ProcessarRetorno(HttpRequest request) {
            if (request == null) {
                request = HttpContext.Current.Request;
            }

            if (request.Form.Count > 0) {
                request.ContentEncoding = Encoding.GetEncoding("iso-8859-1");

                string requestContent = "transacao=" + request["id_transacao"] +
                                    "&status=" + request["status"] +
                                    "&cod_status=" + request["cod_status"] +
                                    "&valor_original=" + request["valor_original"] +
                                    "&valor_loja=" + request["valor_loja"] +
                                    "&token=" + this._token;

                HttpWebRequest NPIRequest = (HttpWebRequest)WebRequest.Create(this._url);
                NPIRequest.Method = WebRequestMethods.Http.Post;
                NPIRequest.ContentType = "application/x-www-form-urlencoded";
                NPIRequest.ContentLength = requestContent.Length;

                StreamWriter writer = new StreamWriter(NPIRequest.GetRequestStream(), request.ContentEncoding);
                writer.Write(requestContent);
                writer.Close();

                StreamReader reader = new StreamReader(NPIRequest.GetResponse().GetResponseStream(), request.ContentEncoding);
                string Response = reader.ReadToEnd();
                reader.Close();

                try {
                    if ("VERIFICADO".Equals(Response, StringComparison.InvariantCultureIgnoreCase) && this.VendaEfetuada != null) {
                        if (this.RetornoVerificado != null) {
                            this.RetornoVerificado(this, new VendaAutenticadaEventArgs() { DadosRequest = requestContent });
                        }
                        this.VendaEfetuada(RetornoVenda.CriarViaRetornoAutomatico(request.Form));
                    } else {
                        if (this.VendaNaoAutenticada != null) {
                            this.VendaNaoAutenticada(this, new VendaNaoAutenticadaEventArgs() { DadosRequest = requestContent, DadosResponse = Response });
                        }
                    }
                } catch (Exception ex) {
                    if (this.FalhaProcessarRetorno != null) {
                        this.FalhaProcessarRetorno(this, new FalhaProcessarRetornoEventArgs() { Exception = ex });
                    }
                }
            }
        }
    }

    public abstract class AutenticacaoVendaEventArgs : EventArgs {
        //Dados constantes no Request efetuado
        private string _dadosRequest;
        public string DadosRequest {
            get {
                return this._dadosRequest;
            }
            set {
                this._dadosRequest = value;
            }
        }
    }

    public class VendaAutenticadaEventArgs : AutenticacaoVendaEventArgs {

    }

    public class VendaNaoAutenticadaEventArgs : AutenticacaoVendaEventArgs {
        //Resposta obtida no Request
        private string _dadosResponse;
        public string DadosResponse {
            get {
                return this._dadosResponse;
            }
            set {
                this._dadosResponse = value;
            }
        }
    }

    public class FalhaProcessarRetornoEventArgs : EventArgs {

        //Mensagem em caso de Erro
        private Exception _exception;
        public Exception Exception {
            get {
                return this._exception;
            }
            set {
                this._exception = value;
            }
        }

    }
}
